package com.bluedot.www.core.service;


import com.bluedot.www.core.common.HandwritingRuntimeException;
import com.bluedot.www.core.common.ResultCodeEnum;
import com.bluedot.www.core.dao.Execute;
import com.bluedot.www.core.pojo.BO.MailBo;
import com.bluedot.www.core.pojo.DO.Right;
import com.bluedot.www.core.pojo.DO.Role;
import com.bluedot.www.core.pojo.DO.User;
import com.bluedot.www.core.pojo.DTO.ReportHistoryDTO;
import com.bluedot.www.core.pojo.DTO.UserDTO;
import com.bluedot.www.core.pojo.DTO.UserHistoryDTO;
import com.bluedot.www.core.utils.DbUtil;
import com.bluedot.www.core.utils.MailUtil;
import com.bluedot.www.core.utils.OSSManageUtil;
import com.bluedot.www.framework.mvc.servlet.http.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * <p>
 * 服务类
 * </p>
 *
 * @author zhouxuan
 * @since 2021-08-07
 */
public class UserService {

    private static final String USER_MAPPER_ADDRESS = "com.bluedot.www.core.mapper.xml.UserMapper.";
    private static final String ROLE_MAPPER_ADDRESS = "com.bluedot.www.core.mapper.xml.RoleMapper.";
    private static final String RIGHT_MAPPER_ADDRESS = "com.bluedot.www.core.mapper.xml.RightMapper.";
    /**
     * 存储邮箱  验证码信息
     **/
    private static final Map<String, List> CODE_MAP = new HashMap<>();
    /**
     * 手动创建线程池
     */
    private static ExecutorService pool = Executors.newCachedThreadPool();

    public static Object execute(String methodName, Object[] param) {
        UserService userService = new UserService();
        Object result = null;
        switch (methodName) {
            case "updateUserInfo":
                result = userService.updateUserInfo((User) param[0]);
                break;
            case "updatePassword":
                result = userService.updatePassword((Long) param[0], (String) param[1], (String) param[2]);
                break;
            case "cancelAccount":
                result = userService.cancelAccount((Long) param[0], (String) param[1]);
                break;
            case "prohibitUserByUserId":
                result = userService.prohibitUserByUserId((Long) param[0], (Integer) param[1]);
                break;
            case "deleteUserByUserId":
                result = userService.deleteUserByUserId((List<Long>) param[0]);
                break;
            case "switchUserByUserId":
                result = userService.switchUserByUserId((Long) param[0], (Long) param[1]);
                break;
            case "findUserByUserId":
                result = userService.findUserByUserId((Long) param[0]);
                break;
            case "login":
                result = userService.login((User) param[0], (HttpServletRequest) param[1], (HttpServletResponse) param[2]);
                break;
            case "register":
                result = userService.register((User) param[0], (String) param[1]);
                break;
            case "findById":
                result = userService.findById((Long) param[0]);
                break;
            case "insertRoleByUserId":
                result = userService.insertRoleByUserId((List<Long>) param[0], (Long) param[1]);
                break;
            case "deleteRoleByUserId":
                result = userService.deleteRoleByUserId((List<Long>) param[0], (Long) param[1]);
                break;
            case "insertAdmin":
                result = userService.insertAdmin((User) param[0]);
                break;
            case "queryUserInfo":
                result = userService.queryUserInfo((Long) param[0]);
                break;
            case "logout":
                userService.logout((HttpServletRequest) param[0]);
                break;
            case "sendRegisterCode":
                result = userService.sendRegisterCode((String) param[0]);
                break;
            case "sendForgetPasswordCode":
                result=userService.sendForgetPasswordCode((String) param[0]);
                break;
            case "fixThreadSendmail":
                fixThreadSendmail((String) param[0],(MailBo)param[1]);
                result = userService.sendForgetPasswordCode((String) param[0]);
                break;
            case "checkEmail":
                result = userService.checkEmail((String) param[0]);
                break;
            case "checkAccount":
                result = userService.checkAccount((String) param[0]);
                break;
            case "checkAccountInfo":
                result = userService.checkAccountInfo((String) param[0], (Long) param[1]);
                break;
            case "forgetPassword":
                result = userService.forgetPassword((String) param[0], (String) param[1], (String) param[2]);
                break;
            case "queryUsersByUserId":
                result = userService.queryUsersByUserId((List<Long>) param[0]);
                break;
            case "insertUser":
                result = userService.insertUser((User) param[0]);
                break;
            case "uploadPortrait":
                result = userService.uploadPortrait((MultipartFile) param[0]);
                break;
            case "queryUserHistory":
                result = userService.queryUserHistory((Long) param[0], (Integer) param[1]);
                break;
            default:
                throw new HandwritingRuntimeException(ResultCodeEnum.METHOD_NOT_FOUND.getCode(),
                        "Method NOT FOUND, method name: " + methodName);
        }
        return result;
    }

    //----------------------------ZhouXuan------------------------

    /**
     * 多线程发送邮件
     *
     * @param location
     * @param mailBo
     * @return void
     * @author jiangnan
     * @date 2021/9/29 20:51
     */
    private static void fixThreadSendmail(String location, MailBo mailBo) {
        pool.execute(new Runnable() {
            @Override
            public void run() {
                MailUtil.sendMail(location, mailBo);
            }
        });
    }

    /**
     * 登录
     *
     * @param user:
     * @param request:
     * @return java.util.List<com.bluedot.www.core.pojo.DO.Right>
     * @author ZhouXuan
     * @date 2021/9/2 13:58
     */
    private User login(User user, HttpServletRequest request, HttpServletResponse response) {
        List<Right> rights = new ArrayList<>();
        UserDTO userDTO = new UserDTO();
        List<User> userInfos = new ArrayList<>();
        User userInfo = null;

        // 通过判断账户中是否有@符号判断它是通过账号或者邮箱进行登录的
        // 判断用户输入的邮箱是否为空，不为空则是通过邮箱登录的
        if (user.getEmail() != null) {
            // 通过邮箱得到用户信息
            List<User> users = (List<User>) Execute.execute(Execute.QUERY_TYPE, USER_MAPPER_ADDRESS + "findByEmail", new Object[]{user.getEmail()});
            if (users.size() > 0) {
                // 密码加密之后，将信息进行验证
                user.setPassword(DbUtil.getMd5(user.getPassword()));
                // 邮箱+密码进行登录
                userInfos = (List<User>) Execute.execute(Execute.QUERY_TYPE, USER_MAPPER_ADDRESS + "findByEmailAndPwd", new Object[]{user});
            }
        }

        // 判断用户输入的账号是否为空，不为空则是通过账号登录的
        if (user.getAccount() != null) {
            // 通过账号得到用户信息
            List<User> users = (List<User>) Execute.execute(Execute.QUERY_TYPE, USER_MAPPER_ADDRESS + "findByAccount", new Object[]{user.getAccount()});
            if (users.size() > 0) {
                // 密码加密之后，将信息进行验证
                user.setPassword(DbUtil.getMd5(user.getPassword()));
                // 账号+密码进行登录
                userInfos = (List<User>) Execute.execute(Execute.QUERY_TYPE, USER_MAPPER_ADDRESS + "findByAccountAndPwd", new Object[]{user});
            }
        }

        // 如果查询到该用户
        if (userInfos.size() == 1) {
            userInfo = userInfos.get(0);
            // 通过用户编号获取该用户的所有角色
            List<Role> roles = (List<Role>) Execute.execute(Execute.QUERY_TYPE, ROLE_MAPPER_ADDRESS + "findByUserId", new Object[]{userInfo.getId()});
            userDTO.setUser(userInfo);
            userDTO.setExistRoles(roles);

            // 设置最后一次登录时间
            userInfo.setLastLogin(DbUtil.getCurrentTime());
            Integer result = (Integer) Execute.execute(Execute.UPDATE_TYPE, USER_MAPPER_ADDRESS + "updateLastLogin", new Object[]{userInfo});
        }

        if (userInfos != null) { // 用户身份正确
            // 将用户信息存储到session中
            HttpSession session = request.getSession();
            session.setAttribute("SESSION_KEY_USER", userDTO);
            response.setHeader("TK",session.getId());
            rights = (List<Right>) Execute.execute(Execute.QUERY_TYPE, RIGHT_MAPPER_ADDRESS + "findAllByUserId", new Object[]{userInfo.getId()});
        }
        return userInfo;
    }

    /**
     * 根据编号得到用户详细信息（包括角色信息）
     */
    public UserDTO findById(Long userId) {
        UserDTO userDTO = new UserDTO();

        // 1.查询出用户信息
        List<User> users = (List<User>) Execute.execute(Execute.QUERY_TYPE,USER_MAPPER_ADDRESS+"findById",new Object[]{userId});
        if (users.size() > 0) {
            userDTO.setUser(users.get(0));
        } else {
            throw new HandwritingRuntimeException(20001, "该用户不存在");
        }

        // 2.查询出它所拥有的角色
        List<Role> roles = (List<Role>) Execute.execute(Execute.QUERY_TYPE, ROLE_MAPPER_ADDRESS + "findByUserId", new Object[]{userId});
        userDTO.setExistRoles(roles);

        // 3.查询出它所未拥有的角色
        List<Role> otherRoles = (List<Role>) Execute.execute(Execute.QUERY_TYPE, ROLE_MAPPER_ADDRESS + "findOtherByUserId", new Object[]{userId});
        userDTO.setNotExistRoles(otherRoles);
        System.out.println(userDTO);
        return userDTO;
    }

    /**
     * 根据用户id，添加、插入多位角色
     * @param roleIds:
     * @param userId:
     * @return boolean
     * @author ZhouXuan
     * @date 2021/9/7 14:23
     */
    private boolean insertRoleByUserId(List<Long> roleIds, Long userId) {
        Map<String, String> map1 = null;
        Map<String, String> map2 = new HashMap<>();

        map2.put("userId", userId.toString());

        Integer sum = 0;
        Integer count;
        for (Long roleId : roleIds) {
            map1 = new HashMap<>();
            map1.put("roleId", roleId.toString());
            count = (Integer) Execute.execute(Execute.UPDATE_TYPE, USER_MAPPER_ADDRESS + "insertRoleByUserId", new Object[]{map1, map2});
            sum += count;
        }

        // 更新完用户-角色表之后，再更新用户表中的userType
        List<Role> roles = (List<Role>) Execute.execute(Execute.QUERY_TYPE, ROLE_MAPPER_ADDRESS + "findByUserId", new Object[]{userId});
        updateUserType(userId, roles);

        return roleIds.size() == sum;
    }

    /**
     * 根据用户id，删除多位角色
     *
     * @param roleIds:
     * @param userId:
     * @return boolean
     * @author ZhouXuan
     * @date 2021/9/7 14:23
     */
    private boolean deleteRoleByUserId(List<Long> roleIds, Long userId) {
        Map<String, String> map1 = null;
        Map<String, String> map2 = new HashMap<>();

        map2.put("userId", userId.toString());

        Integer sum = 0;
        Integer count;
        for (Long roleId : roleIds) {
            map1 = new HashMap<>();
            map1.put("roleId", roleId.toString());
            count = (Integer) Execute.execute(Execute.UPDATE_TYPE, USER_MAPPER_ADDRESS + "deleteRoleByUserId", new Object[]{map1, map2});
            sum += count;
        }

        // 更新完用户-角色表之后，再更新用户表中的userType
        List<Role> roles = (List<Role>) Execute.execute(Execute.QUERY_TYPE, ROLE_MAPPER_ADDRESS + "findByUserId", new Object[]{userId});
        updateUserType(userId, roles);

        return roleIds.size() == sum;
    }

    /**
     * 根据用户实体类，添加、插入一位管理员
     *
     * @param user:
     * @return boolean
     * @author ZhouXuan
     * @date 2021/9/7 14:20
     */
    private boolean insertAdmin(User user) {
        // 设置主键
        user.setId(DbUtil.generateId());

        // 设置时间
        user.setGmtCreate(DbUtil.getCurrentTime());
        user.setGmtModified(DbUtil.getCurrentTime());

        // 设置状态
        user.setStatus(0);
        user.setIsDeleted(0);

        // 密码进行加密
        user.setPassword(DbUtil.getMd5(user.getPassword()));

        // 设置用户类型
        user.setUsertype(2);

        // 1.添加用户信息
        Integer count = (Integer) Execute.execute(Execute.UPDATE_TYPE, USER_MAPPER_ADDRESS + "insertUser", new Object[]{user});

        // 2.添加成功
        Integer result = 0;
        if (count > 0) {
            // 2.1根据用户账号得到用户信息
            List<User> users = (List<User>) Execute.execute(Execute.QUERY_TYPE, USER_MAPPER_ADDRESS + "findByEmail", new Object[]{user.getEmail()});
            List<Role> roles = (List<Role>) Execute.execute(Execute.QUERY_TYPE, ROLE_MAPPER_ADDRESS + "findAll", new Object[]{});
            Long roleId = 0L;
            for (Role role : roles) {
                if ("ADMIN".equals(role.getRoleName())) {
                    roleId = role.getId();
                }
            }
            // 2.2将用户设置成管理员
            Map<String, String> map1 = new HashMap<>();
            Map<String, String> map2 = new HashMap<>();
            map1.put("userId", users.get(0).getId().toString());
            map2.put("roleId", roleId.toString());
            result = (Integer) Execute.execute(Execute.UPDATE_TYPE, USER_MAPPER_ADDRESS + "insertRoleByUserId", new Object[]{map1, map2});
        }

        return result > 0;
    }


    /**
     * 上传头像
     * @param request
     * @return void
     * @author jiangnan
     * @date 2021/9/19 23:13
     */
    /*public void uploadPortrait(HttpServletRequest request){
        ServletInputStream in = null;
        String url = null;
        UserDTO userDTO = (UserDTO)request.getSession().getAttribute("SESSION_KEY_USER");
        User user = userDTO.getUser();
        HashMap<String, Object> map1 = new HashMap<>();
        HashMap<String, Long> map2 = new HashMap<>();
        try {
            in = request.getInputStream();
            url = OSSManageUtil.uploadFile(in, "1.jpg", "bluedot/portrait/");
            map1.put("portrait", url);
            map2.put("id", user.getId());
            Execute.execute(Execute.UPDATE_TYPE,USER_MAPPER_ADDRESS+"updatePortraitByUserId",new Object[]{map1, map2});
            user.setPortrait(url);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }*/

    /**
     * 用于更新用户类型
     *
     * @param id:
     * @param roles:
     * @author ZhouXuan
     * @date 2021/9/8 19:19
     */
    private void updateUserType(Long id, List<Role> roles) {
        Map<String, String> map1 = new HashMap<>();
        Map<String, String> map2 = new HashMap<>();
        String result = "0";
        for (Role role : roles) {
            if ("USER".equals(role.getRoleName())) {
                result = "0";
            } else if ("CONSULTANT".equals(role.getRoleName())) {
                result = "1";
            } else if ("ADMIN".equals(role.getRoleName())) {
                result = "2";
            } else if ("SUPERADMIN".equals(role.getRoleName())) {
                result = "3";
            }
        }
        map1.put("id", id.toString());
        map2.put("usertype", result);
        Execute.execute(Execute.UPDATE_TYPE, USER_MAPPER_ADDRESS + "updateUserTypeById", new Object[]{map1, map2});
    }


    //---------------------------ZhouXuan-------------------------------------

    /**
     * 上传文件至阿里云
     *
     * @param multipartFile:
     * @return java.lang.String 文件连接
     * @author He Peng
     * @date 2021/9/20 19:51
     */
    public String uploadPortrait(MultipartFile multipartFile) {
        String filename = multipartFile.getOriginalFilename();
        String filetype = filename.substring(filename.lastIndexOf(".") + 1);
        if (!"jpg".equals(filetype) && !"png".equals(filetype)) {
            throw new HandwritingRuntimeException(ResultCodeEnum.PARAM_ERROR);
        }
        String url = null;
        try {
            InputStream in = multipartFile.getInputStream();
            url = OSSManageUtil.uploadFile(in, multipartFile.getOriginalFilename(), "bluedot/portrait/");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return OSSManageUtil.getAccessUrl() + url;
    }

    /**
     * 注册  传入邮箱，密码，邮箱验证码
     *
     * @param user 用户对象
     * @param code 邮箱验证码
     * @return boolean
     * @author jiangnan
     * @date 2021/8/8
     */
    private boolean register(User user, String code) {

        String email = user.getEmail();
        String password = user.getPassword();

        String checkCode = null;

        Object[] objects = new Object[1];
        objects[0] = email;

   /*   if((boolean)UserService.execute("sendCode", new Object[]{email})){
          System.out.println("验证码发送成功");
      }
*/     //查询邮箱是否已经使用
        boolean checkEmail = (boolean)UserService.execute("checkEmail", new Object[]{email});

        long time2 = DbUtil.getCurrentTime().getTime();
        ;
        //删除过期邮件
        if (!checkEmail){

            for (String key : CODE_MAP.keySet()) {
                long time = Long.valueOf(String.valueOf(CODE_MAP.get(key).get(0))).longValue();
                long Minutes = (time2 - time) / (1000 * 60);
                if (Minutes > 5) {
                    CODE_MAP.remove(key);
                }
            }

            //获取验证码
            List list = CODE_MAP.get(email);
            if (list.size() != 0) {
                long time1 = (long) list.get(0);
                checkCode = (String) list.get(1);
                if (checkCode.equals(code)) {
//                        System.out.println("开始注册");
                    User user1 = new User();
                    Long id = DbUtil.generateId();
                    Timestamp createTime = DbUtil.getCurrentTime();
                    Timestamp modifiedTime = DbUtil.getCurrentTime();
                    String account = DbUtil.generateAccount();
                    user1.setStatus(0);
                    user1.setId(id);
                    user1.setAccount(account);
                    user1.setDeleted(0);
                    user1.setEmail(email);
                    user1.setPassword(DbUtil.getMd5(password));//md5 加盐
                    user1.setGmtCreate(createTime);
                    user1.setGmtModified(modifiedTime);
                    user1.setUsertype(0);
                    user1.setAccount(DbUtil.generateAccount());
                    user1.setUsertype(0);
                    user1.setPortrait("http://bluedot-a.oss-cn-hangzhou.aliyuncs.com/bluedot/portrait/2021-09-11_9d93e662-cd65-4fd0-901e-0ffe94cdfbed.png");

                    Object[] objects2 = new Object[1];
                    objects2[0] = user1;

                        Integer result = (Integer) Execute.execute(Execute.UPDATE_TYPE,USER_MAPPER_ADDRESS+"insertUser",objects2);
                        System.out.println("注册成功");
                        return result > 0;
                    }else {
                        throw new HandwritingRuntimeException(20009, "验证码错误");
                    }

            }
       }else {
        throw new HandwritingRuntimeException(20008, user.getEmail() + " 此邮箱已存在");
       }
      return false;
     }

    /**
     * 管理员插入用户
     *
     * @param user: User
     * @return boolean
     * @author He Peng
     * @date 2021/9/19 17:03
     */
    private boolean insertUser(User user) {
        Long id = DbUtil.generateId();
        Timestamp createTime = DbUtil.getCurrentTime();
        String portrait = user.getPortrait().replace(OSSManageUtil.getAccessUrl(), "");

        user.setPortrait(portrait);
        user.setStatus(0);
        user.setId(id);
        user.setDeleted(0);
        user.setGmtCreate(createTime);
        user.setGmtModified(createTime);
        user.setUsertype(0);

        // md5 加密
        user.setPassword(DbUtil.getMd5(user.getPassword()));
        Integer result = (Integer) Execute.execute(Execute.UPDATE_TYPE, USER_MAPPER_ADDRESS + "insertUser", new Object[]{user});
        Integer roleId = findRoleIdByRoleName("普通用户");

        //分配角色
        //用户角色表加一条数据
        Map<String, String> map1 = new HashMap<>();
        Map<String, String> map2 = new HashMap<>();
        map1.put("userId", id.toString());
        map2.put("roleId", roleId.toString());
        Integer result1 = (Integer) Execute.execute(Execute.UPDATE_TYPE, USER_MAPPER_ADDRESS + "insertRoleByUserId", new Object[]{map1, map2});

        return result > 0 && result1 > 0;
    }




    /**
     * 展示用户个人信息
     *
     * @param userId 用户id
     * @return User
     * @author jiangnan
     * @date 2021/8/8
     */
    private User queryUserInfo(Long userId) {

        List<User> user = (List<User>) Execute.execute(Execute.QUERY_TYPE, USER_MAPPER_ADDRESS + "queryUserInfoById", new Object[]{userId});

        return user.get(0);
    }
    /*
     *//**
     *  根据id查找account
     * @param null
     * @return
     * @author jiangnan
     * @date 2021/10/7 19:58
     *//*
    private String findAccountById(Long id){
        return
    }
    */

    /**
     * 更新用户个人信息
     *
     * @param user 用户对象
     * @return boolean
     * @author Deng HongWei
     * @date 2021/8/8
     */
    private boolean updateUserInfo(User user) {


        if (checkAccount(user.getAccount()) || user.getAccount().equals(findUserByUserId(user.getId()).getAccount())) {
            user.setGmtModified(DbUtil.getCurrentTime());
            return (Integer) Execute.execute(Execute.UPDATE_TYPE, USER_MAPPER_ADDRESS + "updateUserInfo", new User[]{user}) > 0;
        }
        return false;
    }

    /**
     * 检查密码是否正确
     *
     * @param userId   用户id
     * @param password 密码
     * @return boolean
     * @author Deng HongWei
     * @date 2021/9/1 20:47
     */
    private boolean checkPassWord(Long userId, String password) {
        HashMap<String, String> map1 = new HashMap<>();
        HashMap<String, String> map2 = new HashMap<>();
        map1.put("userId", userId.toString());
        map2.put("password", DbUtil.getMd5(password));
        List<User> users = (List<User>) Execute.execute(Execute.QUERY_TYPE, USER_MAPPER_ADDRESS + "checkPassWord", new Object[]{map1, map2});
        System.out.println(users);
        return users.size() > 0;
    }

    /**
     * 重置密码 根据用户id查询到旧密码，判断是否与输入的相等，然后更新新密码
     *
     * @param userId      用户id
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @return boolean
     * @author Deng HongWei
     * @date 2021/8/8
     */
    private boolean updatePassword(Long userId, String oldPassword, String newPassword) {
        boolean flag = checkPassWord(userId, oldPassword);
        if (!flag) {
            return false;
        }
        HashMap<String, Object> map1 = new HashMap<>();
        HashMap<String, String> map2 = new HashMap<>();
        map1.put("userId", userId);
        map2.put("newPassword", DbUtil.getMd5(newPassword));
        return (Integer) Execute.execute(Execute.UPDATE_TYPE, USER_MAPPER_ADDRESS + "updatePassword", new Object[]{map1, map2}) > 0;
    }

    /**
     * 注销账户:根据用户id删除用户
     *
     * @param userId 用户id
     * @return boolean
     * @author Deng HongWei
     * @date 2021/8/8
     */
    private boolean cancelAccount(Long userId, String password) {
        boolean flag = checkPassWord(userId, password);
        if (!flag) {
            return false;
        }
        return (Integer) Execute.execute(Execute.UPDATE_TYPE, USER_MAPPER_ADDRESS + "cancelAccount", new Object[]{userId}) > 0;
    }

    /**
     * 检查邮箱是否已被注册
     *
     * @param email 邮箱
     * @return boolean   true：已被注册   FALSE：未被注册
     * @author jiangnan
     * @date 2021/8/8
     */
    private boolean checkEmail(String email) {
        boolean flag = true;
        List<User> list = (List<User>) Execute.execute(Execute.QUERY_TYPE, USER_MAPPER_ADDRESS + "isExistEmail", new Object[]{email});
        if (list.size() == 0) {
            flag = false;
        }
        System.out.println(flag);
        return flag;
    }

    /**
     * 检查账户名是否已使用
     *
     * @param account
     * @return true 未被使用  false 已被使用
     * @author jiangnan
     * @date 2021/10/7 18:53
     */
    private boolean checkAccount(String account) {
        boolean flag = false;
        List<User> list = (List<User>) Execute.execute(Execute.QUERY_TYPE, USER_MAPPER_ADDRESS + "isExistAccount", new Object[]{account});
        if (list.size() == 0) {
            flag = true;
        }

        return flag;
    }

    /**
     *   检查账户名是否已使用
     * @param account
     * @param userId
     * @return boolean   true 可以保存  false 已被使用，不可以保存
     * @author jiangnan
     * @date 2021/11/18 14:47
     */
    private boolean checkAccountInfo(String account,Long userId) {
        String userAccount = findUserByUserId(userId).getAccount();
//        System.out.println(userAccount);
        if (account.equals(userAccount)){
            return true;
        }else{
            boolean flag = false;
            List<User> list = (List<User>) Execute.execute(Execute.QUERY_TYPE, USER_MAPPER_ADDRESS + "isExistAccount", new Object[]{account});
            if (list.size() == 0) {
                flag = true;
            }

            return flag;
        }
    }





    /**
     * 退出
     *
     * @param request
     * @author jiangnan
     * @date 2021/8/8
     */
    private void logout(HttpServletRequest request) {
        request.getSession().removeAttribute("SESSION_KEY_USER");
    }

    /**
     * 发送注册邮箱验证码
     *
     * @param email 邮箱
     * @author jiangnan
     * @date 2021/8/8
     */
    private boolean sendRegisterCode(String email) {

        //查询邮箱是否已经使用
        boolean checkEmail = (boolean)UserService.execute("checkEmail", new Object[]{email});
        if (!checkEmail) {
            String emailrule = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$";
            if (email.matches(emailrule)) {
                String code = MailUtil.getCode();
                String html = null;
                try {
                    File file = new File(this.getClass().getResource("/static/code.html").getPath());
                    html = MailUtil.readHTML(file);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                MailBo mailBo = new MailBo(email, "Verification", html, "欢迎注册", code);

                fixThreadSendmail("application.properties", mailBo);
                //将验证码信息存入pipe管道中 参数有:接收邮箱,生成时间,验证码
                ArrayList<Object> list = new ArrayList<>();
                list.add(DbUtil.getCurrentTime().getTime());
                list.add(code);
                CODE_MAP.put(email, list);

            } else {
                throw new HandwritingRuntimeException(20002, "邮箱格式错误");
            }
        }else{
            throw new HandwritingRuntimeException(20002, "邮箱已被注册");
        }

        return true;


    }

    /**
     * 发送忘记密码邮箱验证码
     *
     * @param email 邮箱
     * @author jiangnan
     * @date 2021/8/8
     */
    private boolean sendForgetPasswordCode(String email) {
        String emailrule = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$";
        boolean flag = false;
        if (email.matches(emailrule)) {
            String code = MailUtil.getCode();
            String html = null;
            try {
                File file = new File(this.getClass().getResource("/static/code.html").getPath());
                html = MailUtil.readHTML(file);
            } catch (IOException e) {
                e.printStackTrace();
            }
            MailBo mailBo = new MailBo(email, "fogetPassword", html, "忘记密码", code);

            fixThreadSendmail("application.properties", mailBo);
            flag = true;
            //将验证码信息存入pipe管道中 参数有:接收邮箱,生成时间,验证码
            ArrayList<Object> list = new ArrayList<>();
            list.add(DbUtil.getCurrentTime().getTime());
            list.add(code);
            CODE_MAP.put(email, list);

        } else {
            System.out.println("邮箱格式不正确");
        }
        return flag;


    }


    /**
     * 忘记密码  传入邮箱,发送邮箱验证码,输入验证码，比较是否相等，再输入新密码
     *
     * @param email       邮箱
     * @param code        邮箱验证码
     * @param newPassword 新密码
     * @return boolean
     * @author jiangnan
     * @date 2021/8/8 15:51
     */
    private boolean forgetPassword(String email, String newPassword, String code) {

        boolean flag = false;
        String checkCode = null;

       /* if((boolean)UserService.execute("sendCode", new Object[]{email})){
            System.out.println("验证码发送成功");
        }*/
        List<User> u = (List<User>) Execute.execute(Execute.QUERY_TYPE, USER_MAPPER_ADDRESS + "queryUserByEmail", new Object[]{email});
        if (u.size() != 0) {

            long time2 = DbUtil.getCurrentTime().getTime();
            List list = CODE_MAP.get(email);
            if (list.size() != 0) {

                //删除过期邮件
                for (String key : CODE_MAP.keySet()) {
                    long time = Long.valueOf(String.valueOf(CODE_MAP.get(key).get(0))).longValue();
                    long Minutes = (time2 - time) / (1000 * 60);
                    if (Minutes > 5) {
                        CODE_MAP.remove(key);
                    }
                }

                long time1 = (long) list.get(0);

                checkCode = (String) list.get(1);
                if (checkCode.equals(code)) {
                    String password = DbUtil.getMd5(newPassword);

                    Object[] objects = new Object[2];
                    Map map1 = new HashMap<String, Object>(1);
                    map1.put("newPassword", password);

                    Map map2 = new HashMap<String, Object>(1);
                    map2.put("userId", u.get(0).getId());

                    objects[0] = map1;
                    objects[1] = map2;

                    if ((Integer) Execute.execute(Execute.UPDATE_TYPE, USER_MAPPER_ADDRESS + "updatePassword", objects) > 0) {
                        flag = true;
                    }
                    return flag;
                } else {
                    System.out.println("验证码错误");
                }

            }
        }else {
            throw new HandwritingRuntimeException(20001, "用户不存在");
        }

        return flag;
    }


//==================================================================================================

    /**
     * 通过用户id封禁用户
     *
     * @param userId     用户id
     * @param userStatus 该用户的封禁状态 就两种值 一个是0表示正常 一个是1表示封禁
     * @return Boolean
     * @author Ding YuXing
     * @date 2021/8/8 10:01
     */
    private Boolean prohibitUserByUserId(Long userId, Integer userStatus) {
        Integer usertype = findUsertypeByUserId(userId);
        //将管理员和超级管理员过滤
        if (usertype == 2 || usertype == 3) {
            return false;
        }


        if (userStatus == 0) {
            //表示接下来要封禁
            Integer Result = (Integer) Execute.execute(Execute.UPDATE_TYPE, USER_MAPPER_ADDRESS + "prohibitUserByUserId", new Object[]{userId});
            return Result > 0;
        } else {
            //接下来要解禁
            Integer Result2 = unBanUserByUserId(userId);
            return Result2 > 0;
        }
    }

    /**
     * 通过用户id解禁用户
     *
     * @param userId 用户id
     * @return Integer
     * @author Ding YuXing
     * @date 2021/8/8 10:01
     */
    private Integer unBanUserByUserId(Long userId) {
        Integer Result = (Integer) Execute.execute(Execute.UPDATE_TYPE, USER_MAPPER_ADDRESS + "unBanUserByUserId", new Object[]{userId});
        return Result;
    }

    /**
     * 通过用户id查询用户类型usertype
     *
     * @param userId 用户id
     * @return Integer
     * @author Ding YuXing
     * @date 2021/8/8 10:01
     */
    private Integer findUsertypeByUserId(Long userId) {
        List<User> user = (List<User>) Execute.execute(Execute.QUERY_TYPE, USER_MAPPER_ADDRESS + "findUsertypeByUserId", new Object[]{userId});
        return user.get(0).getUsertype();
    }

    /**
     * 通过用户id删除用户
     *
     * @param userIds 用户id
     * @return Boolean
     * @author Ding YuXing
     * @date 2021/8/8 10:01
     */
    private Boolean deleteUserByUserId(List<Long> userIds) {
        List<Long> lastUserIds = new ArrayList<>();
        for (Long userId : userIds) {
            Integer usertype = findUsertypeByUserId(userId);
            if (usertype == 0 || usertype == 1) {
                lastUserIds.add(userId);
            }
        }

        int i = 0;
        for (Long lastUserId : lastUserIds) {
            Integer result = (Integer) Execute.execute(Execute.UPDATE_TYPE, USER_MAPPER_ADDRESS + "deleteUserByUserId", new Object[]{lastUserId});
            if (result == 1) {
                i++;
            }
        }
        return i == lastUserIds.size();


    }

    /**
     * 通过用户id切换用户类型
     * 这里显示的用户
     * 不会显示被删除的用户
     * 但是会显示被封禁的用户
     *
     * @param userId 用户id
     * @param roleId 只有两个值 第一个是心理咨询师对应1 第二个是普通用户对应0
     * @return Boolean
     * @author Ding YuXing
     * @date 2021/8/8 10:02
     */
    private Boolean switchUserByUserId(Long userId, Long roleId) {
        String beforeRoleName = null;
        String roleName = null;

        Integer usertype = findUsertypeByUserId(userId);
        //将管理员和超级管理员过滤
        if (usertype == 2 || usertype == 3) {
            return false;
        }

        //要修改的角色跟当前角色相同
        if (roleId.intValue() == usertype) {
            return true;
        }
        //下面是将普通用户变成心理咨询师 或者 将心理咨询师变为用户
        //修改 userId 对应的用户 usertype 字段 0变1 1变0
        String userIds = Long.toString(userId);
        String roleIds = Long.toString(roleId);

        Object[] objects = new Object[2];

        Map map = new HashMap<String, Object>(1);
        map.put("userId", userIds);

        Map map2 = new HashMap<String, Object>(1);
        map2.put("roleId", roleIds);

        objects[0] = map;
        objects[1] = map2;

        Integer result = (Integer) Execute.execute(Execute.UPDATE_TYPE, USER_MAPPER_ADDRESS + "switchUserByUserId", objects);

        //如果roleId是0 那么角色名称是普通用户 是1就是心理咨询师
        if (roleId == 0) {
            //这是要改变的角色名字 原来的角色名字是反过来的
            roleName = "普通用户";
            beforeRoleName = "心理咨询师";
        } else {
            roleName = "心理咨询师";
            beforeRoleName = "普通用户";
        }

        //要修改的角色名字对应的id
        Integer roleIdByRoleName = findRoleIdByRoleName(roleName);
        //原来的角色名字对应的id
        Integer beforeRoleId = findRoleIdByRoleName(beforeRoleName);

        String roleIdByRoleNameStr = Integer.toString(roleIdByRoleName);
        String beforeRoleIdStr = Integer.toString(beforeRoleId);

        //通过 用户id 旧角色id 和 新角色id 更新用户角色表
        Integer updateUserRole = updateUserRole(userIds, beforeRoleIdStr, roleIdByRoleNameStr);

        return result == 1 && updateUserRole == 1;
    }

    /**
     * 通过角色名称查询角色id
     *
     * @param roleName 角色名称
     * @return Integer
     * @author Ding YuXing
     * @date 2021/8/8 10:02
     */
    private Integer findRoleIdByRoleName(String roleName) {
        List<Role> roles = (List<Role>) Execute.execute(Execute.QUERY_TYPE, USER_MAPPER_ADDRESS + "findRoleIdByRoleName", new Object[]{roleName});
        return roles.get(0).getId().intValue();
    }

    /**
     * 通过 用户id 旧角色id 和 新角色id 更新用户角色表
     *
     * @param userId       用户id
     * @param beforeRoleId 旧角色id
     * @param roleId       新角色id
     * @return Integer
     * @author Ding YuXing
     * @date 2021/9/1 23:16
     */
    private Integer updateUserRole(String userId, String beforeRoleId, String roleId) {
        Object[] objects = new Object[3];

        Map map1 = new HashMap<String, Object>(1);
        map1.put("userId", userId);

        Map map2 = new HashMap<String, Object>(1);
        map2.put("beforeRoleId", beforeRoleId);

        Map map3 = new HashMap<String, Object>(1);
        map3.put("roleId", roleId);

        objects[0] = map1;
        objects[1] = map2;
        objects[2] = map3;

        Integer result = (Integer) Execute.execute(Execute.UPDATE_TYPE, USER_MAPPER_ADDRESS + "updateUserRole", objects);

        return result;
    }

    /**
     * 查看用户详情 通过用户id查该用户信息
     *
     * @param userId 用户id
     * @return User
     * @author Ding YuXing
     * @date 2021/8/8 10:03
     */
    private User findUserByUserId(Long userId) {
        List<User> user = (List<User>) Execute.execute(Execute.QUERY_TYPE, USER_MAPPER_ADDRESS + "findUserByUserId", new Object[]{userId});
        if (user.size() > 0) {
            return user.get(0);
        }
        return null;
    }

    /**
     * 通过多个用户id查询多个用户信息
     *
     * @param userIds 用户编号
     * @return List<User>
     * @author Ding YuXing
     * @date 2021/9/13 14:56
     */
    private List<User> queryUsersByUserId(List<Long> userIds) {
        List<User> users = new ArrayList<>();
        for (Long userId : userIds) {
            User user = findUserByUserId(userId);
            users.add(user);
        }
        return users;
    }

    /**
     * 获取用户的历史记录
     * @param userId: 用户编号
     * @param status: 是否查询未分析的性格报告，-1：查询所有，0：表示查询已分析，1：表示查询未分析性格报告
     * @return com.bluedot.www.core.pojo.DTO.UserHistoryDTO
     * @author He Peng
     * @date 2021/10/30 14:59
     */
    private UserHistoryDTO queryUserHistory(Long userId, Integer status) {
        User user = findUserByUserId(userId);
        UserHistoryDTO userHistoryDTO = new UserHistoryDTO();
        userHistoryDTO.setUserId(userId);
        String gender = user.getGender() == 0 ? "男" : "女";
        userHistoryDTO.setGender(gender);
        userHistoryDTO.setName(user.getName());
        // 表示为用户类型
        Integer type = 0;
        List<ReportHistoryDTO> reportHistoryList = (List<ReportHistoryDTO>) CharacterReportService.execute(
                "queryReportHistoryCondition",
                new Object[]{userId, type, status});
        userHistoryDTO.setReportHistoryList(reportHistoryList);
        return userHistoryDTO;
    }


}
